package com.qnbc.mystery.controller;
//收藏Controller

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qnbc.mystery.config.interceptor.AuthAccess;
import com.qnbc.mystery.core.domain.AjaxResult;
import com.qnbc.mystery.domain.BoxInfo;
import com.qnbc.mystery.pojo.domain.Collect;
import com.qnbc.mystery.pojo.domain.Recommend;
import com.qnbc.mystery.service.IBoxInfoService;
import com.qnbc.mystery.service.ICollectService;
import com.qnbc.mystery.utils.MPUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.mahout.cf.taste.common.TasteException;
import org.apache.mahout.cf.taste.impl.common.FastByIDMap;
import org.apache.mahout.cf.taste.impl.common.LongPrimitiveIterator;
import org.apache.mahout.cf.taste.impl.model.GenericDataModel;
import org.apache.mahout.cf.taste.impl.model.GenericPreference;
import org.apache.mahout.cf.taste.impl.model.GenericUserPreferenceArray;
import org.apache.mahout.cf.taste.impl.recommender.GenericItemBasedRecommender;
import org.apache.mahout.cf.taste.impl.similarity.UncenteredCosineSimilarity;
import org.apache.mahout.cf.taste.model.DataModel;
import org.apache.mahout.cf.taste.model.Preference;
import org.apache.mahout.cf.taste.model.PreferenceArray;
import org.apache.mahout.cf.taste.recommender.RecommendedItem;
import org.apache.mahout.cf.taste.recommender.Recommender;
import org.apache.mahout.cf.taste.similarity.ItemSimilarity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/collect")
public class CollectController {

    @Autowired
    private ICollectService collectService;
    //推荐数量
    public static int cfCount = 4;

    @Autowired
    private IBoxInfoService fuwuxinxiService;

    @RequestMapping("/del")
    @Transactional
    public AjaxResult del(Integer id, HttpServletRequest request) {
        Object id1 = request.getSession().getAttribute("userId");
        collectService.remove(new LambdaQueryWrapper<Collect>().eq(Collect::getProductid, id).eq(Collect::getUserid, id1));
        return AjaxResult.success();
    }


    @RequestMapping("/list")
    @Transactional
    public AjaxResult list(HttpServletRequest request) {
        Object id1 = request.getSession().getAttribute("userId");
        QueryWrapper<Collect> eq = new QueryWrapper<Collect>().eq("user_id", id1);
        List<Collect> collectEntities = collectService.list(eq);

//        collectEntities.forEach(collect -> {
//            collect.setFuwuxinxiVO(fuwuxinxiService.selectVO(new EntityWrapper<FuwuxinxiEntity>().eq("id", collect.getProductId())));
//        });
        return AjaxResult.success().put("data", collectEntities);
    }

    //创建订单 返回订单号
    @GetMapping("/create")
    @Transactional
    public AjaxResult create(Integer id, HttpServletRequest request) {
        Object id1 = request.getSession().getAttribute("userId");
        QueryWrapper<Collect> eq = new QueryWrapper<Collect>().eq("user_id", id1).eq("product_id", id);
        Collect one = collectService.getOne(eq);

        if (null != one) {
            return AjaxResult.error("请勿重复收藏");
        }

        Collect collect = new Collect();
        collect.setUserid(id1.toString());
        collect.setProductid(Long.valueOf(id));
        collectService.save(collect);
        return AjaxResult.success("收藏成功");
    }


    /**
     * 查询某个用户的推荐歌曲列表
     */
    @AuthAccess
    @RequestMapping(value = "/topRecommendOfUserId", method = RequestMethod.GET)
    public AjaxResult topRecommendOfUserId(@RequestParam Map<String, Object> params, BoxInfo jiankangzixun, HttpServletRequest request) {
        String uId = String.valueOf(request.getSession().getAttribute("userId"));
        System.out.println("当前用户：" + uId);
        String userId = "1";//用户id
        if (StringUtils.isNotEmpty(uId) && !uId.equals("null")) {
            userId = uId;
        }
        if (Objects.equals(userId, "1")) {
            QueryWrapper<Collect> ew = new QueryWrapper<Collect>();
            ew.allEq(MPUtil.allEQMapPre(new Collect(), "storeup"));
            List<Collect> list = collectService.list(ew);
            List<Recommend> allRecommend = new ArrayList<Recommend>();
            List<Long> cfItemIds = new ArrayList<Long>();
            for (Collect col : list) {
                Recommend r = new Recommend();
                r.setUserId(Long.valueOf(col.getUserid()));
                r.setSongId(col.getProductid());
                r.setCommend(1);
                allRecommend.add(r);
            }
            DataModel dataModel = getDadaModel(allRecommend);
            cfItemIds = baseItem(Long.valueOf(userId), dataModel);
            if (cfItemIds != null) {
                List<BoxInfo> ls = new ArrayList<>();
                for (Long l : cfItemIds) {
                    BoxInfo s = fuwuxinxiService.getById(l);
                    if (s != null) {
                        ls.add(s);
                    }
                }

                if (ls.size() < 4) {
                    List<Long> collect = ls.stream().map(BoxInfo::getId).collect(Collectors.toList());
                    int size = ls.size();
                    List<BoxInfo> fuwuxinxiEntities = fuwuxinxiService.list(new QueryWrapper<BoxInfo>().notIn("id", collect));
                    if (fuwuxinxiEntities.size() < 4 - size) {
                        ls.addAll(fuwuxinxiEntities);
                    } else {
                        ls.addAll(fuwuxinxiEntities.subList(0, 4 - size));
                    }
                }

                return AjaxResult.success().put("data", ls);
            }
        }
        return AjaxResult.success();
    }

    /**
     * 根据数据库表数据，得到用户-音乐收藏分数矩阵
     *
     * @param allRecommend
     * @return
     */
    public DataModel getDadaModel(List<Recommend> allRecommend) {
        System.out.println("数据库表的数据总数： " + allRecommend.size());
        if (allRecommend.size() > 0) {
            Map<Long, List<Preference>> map = new HashMap<Long, List<Preference>>();
            for (Recommend rItem : allRecommend) {
                List<Preference> preferenceList = new ArrayList<Preference>();
                Long userId = rItem.getUserId();
                Long songId = rItem.getSongId();
                Integer commend = rItem.getCommend();
                Integer preference = 0;
                if (commend != 0) {
                    preference = commend;
                    preferenceList.add(new GenericPreference(userId, songId, preference));
                    if (map.containsKey(userId)) {
                        List<Preference> preferenceListTemp = map.get(userId);
                        preferenceListTemp.addAll(preferenceList);
                        map.put(userId, preferenceListTemp);
                    } else {
                        map.put(userId, preferenceList);
                    }
                }
            }

            FastByIDMap<PreferenceArray> preferences = new FastByIDMap<PreferenceArray>();
            Set<Long> set = map.keySet();
            for (Long i : set) {
                List<Preference> preList = map.get(i);
                preferences.put(i, new GenericUserPreferenceArray(preList));
            }
            DataModel model = new GenericDataModel(preferences);
            return model;

        } else {
            System.out.println("******数据库中没有任何音乐收藏记录！******");
            return null;
        }
    }

    /**
     * 基于音乐的协同过滤推荐
     *
     * @param userId
     * @param model
     * @return
     */
    public List<Long> baseItem(Long userId, DataModel model) {
        if (model == null) {
            return null;
        }
        try {
            ItemSimilarity similarity = new UncenteredCosineSimilarity(model);
            LongPrimitiveIterator iterator = model.getItemIDs();
            long idTemp = iterator.next();
            while (iterator.hasNext()) {
                long id = iterator.next();
                double sim = similarity.itemSimilarity(idTemp, id);
            }
            Recommender recommender = new GenericItemBasedRecommender(model, similarity);
            List<RecommendedItem> items = recommender.recommend(userId, cfCount);
            List<Long> cfItemIds = new ArrayList<Long>();
            System.out.println("推荐岗位id集合：");
            for (RecommendedItem ri : items) {
                Long itemid = ri.getItemID();
                cfItemIds.add(itemid);
            }
            System.out.println(cfItemIds);
            return cfItemIds;
        } catch (TasteException e) {
            e.printStackTrace();
        }
        return null;
    }

}
